/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Network;

import chataudio.Constant;
import controleur.AbstractChatControleur;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author user
 */
public class autodiscover  extends Thread
{
    AbstractChatControleur controleur;
    DatagramSocket server ;
    boolean running = true;
    String myip;
     
    /**
    *<b>Constructeur autodiscover</b>
    * @return controleur 
    */
    public autodiscover(AbstractChatControleur controleur) throws IOException 
    {
        this.controleur = controleur;
        server = new DatagramSocket(Constant.autodiscoverPort);
        server.setSoTimeout(500);
        this.start();
    }
    
    
    @Override
   public void run() 
    {
                byte[] receiveData = new byte[2]; 
        while (running) {
            try {
                
                // Reception 
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); 
                server.receive(receivePacket);
                
                String ip = receivePacket.getAddress().getHostAddress();
                
                if ( receivePacket.getData()[0] == 1)  // Retour comme quoi il est en ligne
                {                
                    // OK - new connection
                    //System.out.println(myip);
                    if ( ! ip.equals(myip) )
                        controleur.createConnection(ip);
                }
                else // renvoie comme koi je suis en ligne
                {               
                    if (controleur.isEnableAutodiscover()) // repond si l'autodiscover est active
                    {

                        byte[] data = {1, 0}; // 1 = code creation conection distante 
                        DatagramSocket socket = new DatagramSocket();
                        SocketAddress sa = new InetSocketAddress(ip, Constant.autodiscoverPort);
                        DatagramPacket outPacket = new DatagramPacket(
                                data,
                                data.length,
                                InetAddress.getByName(ip),
                                Constant.autodiscoverPort);
                        socket.send(outPacket);
                    }
                }
                    
            } catch (IOException ex) {
            }
        }
        
        server.close();
    }
        
    
    /**
    *<b>Methode arret</b>
    * arrete le thraed 
    */
    public void arret()
    {
        running = false;
    }
        
    
    public void discover() throws UnknownHostException, IOException
    {
        getMyIp();
    } 
    
    /**
    *<b>Methode scan</b>
    * envoie 2 octets a chaque IP du subnet 
    */
   public void scan(String myip) throws UnknownHostException, IOException
    {
        this.myip = myip;
        
        //System.out.println(myip);
        String[] bloc = myip.split("\\.");
        String subnet = bloc[0] + "." + bloc[1] + "." + bloc[2] + "." ;
        
        
        byte[] data = { 0, 0 };
        System.out.println(subnet);
        
        if ( ! bloc[0].equals("127")) // Si ce n'est pas 127.0.0.1
        for ( int i=0; i<255; i++)
        {
            String ip = subnet +i;
            DatagramSocket socket = new DatagramSocket();
            
            if (!ip.equals(myip)) {
                try {

                    DatagramPacket outPacket = new DatagramPacket(
                            data,
                            data.length,
                            InetAddress.getByName(ip),
                            Constant.autodiscoverPort);
                    socket.send(outPacket);


                } catch (Exception e) {
                }
            }
        }
        
    }
    
   
    /**
    *<b>Methode getMyIp</b>
    * Recupere les adresses IP des interfaces locales
    */
    public void getMyIp() throws SocketException, UnknownHostException, IOException
    {
        for (Enumeration<NetworkInterface> ifaces = 
               NetworkInterface.getNetworkInterfaces();
             ifaces.hasMoreElements(); )
        {
            NetworkInterface iface = ifaces.nextElement();
            //System.out.println(iface.getName() + ":");
            for (Enumeration<InetAddress> addresses =
                   iface.getInetAddresses();
                 addresses.hasMoreElements(); )
            {
                InetAddress address = addresses.nextElement();
                String ip = address.getHostAddress().replaceAll("/","");
                
                // ne prend pas les IPv6
                if ( isIPv4(ip))
                    scan(ip);
            }
        }

    }
    
    
    /**
    *<b>Methode isIPv4</b>
    * Test si l'IP passé est une au format IPv4
    */
    public boolean isIPv4(String IP)
    {
        Pattern pattern = Pattern.compile("^\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b$");        
        return pattern.matcher(IP).matches();
    }
    
}
